import { Sprite, SpriteFrame, UITransform, Node, Size } from 'cc'
import { UserInfo } from '../common/UserInfo'
import { buildingDescList, buildingType, raceType, bProperty, EventType } from '../settings/const'
import { Space } from '../village/Space'
import { VillageController } from '../village/VillageController'
import { BuildingCondition } from './BuildingCondition'
import { Events } from './Events'
import ResManager from '../common/ResManager'
import { BManager } from './BManager'
import { Tech } from './Tech'

export enum EventOper {
    CANCEL = 1,
    SPEED_BUILD = 2,
    SPEED_REMOVE = 3,
}
export enum DiamondConsume {
    BUILD = 2,
    REMOVE = 5
}

export class Building extends BManager {
    /**建筑物的id */
    id: number
    name: string
    desc: string
    condition: string
    /**建筑物的等级 */
    level?: number
    wood?: number
    mud?: number
    iron?: number
    food?: number
    people?: number
    culture?: number
    increase?: number
    time?: number
    maxLevel?: number

    // lackLevel?: string[]
    // needLevel?: {
    //     id: number,
    //     name: string,
    //     level: number,
    //     isLack?: boolean,
    //     isExit?: boolean,
    //     type?:string

    // }[]


    /**根据 id 来创建 Buildings 对象 */
    public static createById = (id: number): Building => {
        let b = new Building()
        b.id = id
        b.name = buildingDescList[id][0]
        b.desc = buildingDescList[id][1].replace(/<[^>]+>/g, '').replace(/&nbsp;/g, '；').replace(/•/g, '')
        b.condition = buildingDescList[id][2].replace(/<[^>]+>/g, '').replace(/&nbsp;/g, '；').replace(/•/g, '')
        return b
    }
    /**根据 id,level(id,level;id,level;....) 字符串来创建建筑 */
    public static createByIdLevelStr(str: string) {
        let arr = str.trim().split(',');
        let id = parseInt(arr[0])
        let level = parseInt(arr[1])
        return Building.createByIdAndLevel(id, level)
    }
    /**
     * 根据 id 和 level（等级）来 建筑物对象 
     * @param id 建筑id
     * @param level 建筑等级
     * @returns 
     */
    public static createByIdAndLevel = (id: number, level: number): Building => {
        let d = Building.createById(id)
        let proList = bProperty[id]
        let pro = proList[level]
        let maxLevel = 0
        for (let item of proList) {
            if (item[0] > maxLevel) {
                maxLevel = item[0]
            }
        }
        // 如果企图获取超过满级的数据，则直接放回
        if (level > maxLevel) {
            return d
        }

        d.level = pro[0]
        d.wood = pro[1]
        d.mud = pro[2]
        d.iron = pro[3]
        d.food = pro[4]
        d.people = pro[5]
        d.culture = pro[6]
        d.increase = pro[7]
        d.time = pro[8]
        d.maxLevel = maxLevel


        return d

    }
    /**
     * 根据BManager对象，创建建筑物对象
     * @param b 
     * @returns 
     */
    public static createBuildingByBManager(b: BManager): Building {
        if (!b) {
            return null
        }

        let build = Building.createByIdAndLevel(b.gid, b.grade)
        build.gid = b.gid
        build.grade = b.grade
        build.instantHint = b.instantHint
        build.uid = b.uid

        return build
    }
    /**获取所有种类的建筑物对象 */
    public static createAllBuilding(race:number = -1): Building[] {
        if(race == -1){
            race = UserInfo.instance.race
        }
       
        // 不让建造的建筑物
        let exclude = [
            buildingType.B05_Sawmill,
            buildingType.B06_Brickyard,
            buildingType.B07_Foundry,
            buildingType.B08_GrainMill,
            buildingType.B09_Bakery,
            buildingType.B12_Blacksmith,
            buildingType.B13_Armoury,
            buildingType.B20_Stable,
            buildingType.B28_TradeOffice,
            buildingType.B29_G_Barracks,
            buildingType.B30_G_Stable,
            buildingType.B31_H_Wall,
            buildingType.B32_X_Wall,
            buildingType.B33_M_Wall,
            buildingType.B35_Brewery,
            buildingType.B40_Wonder,
        ]
        let list = []
        for (let key in buildingType) {
            let id = buildingType[key]

            if (exclude.includes(id)) {
                
                continue
            }

            list.push(Building.createByIdAndLevel(id, 1))
        }

        if(race == raceType.Rome){
            list.push(Building.createByIdAndLevel( buildingType.B31_H_Wall, 1))
        }
        if(race == raceType.Teuton){
            list.push(Building.createByIdAndLevel(buildingType.B32_X_Wall, 1))
        }
        if(race == raceType.Gaul){
            list.push(Building.createByIdAndLevel(buildingType.B33_M_Wall, 1))
        }

        return list
    }
    /**
     * 获取我的建筑物列表
     */
    public static getMyBuildings(): Building[] {
        let list = UserInfo.instance.buildings
        for (let i = list.length - 1; i >= 0; i--) {
            if (list[i].gid == 0) {
                list.splice(i, 1)
            }
        }

        let arr = []
        for (let item of list) {
            arr.push(Building.createBuildingByBManager(item))
        }

        return arr
    }
    /**
     * 获取我的资源田列表
     * @returns 
     */
    public static getMyRes(): Building[] {
        let list = UserInfo.instance.resource
        list.sort((a, b) => {
            return a.gid - b.gid
        })
        
        let arr = []
        for (let item of list) {
            arr.push(Building.createBuildingByBManager(item))
        }

        return arr
    }

    /**
     * 获取建筑物的图片
     * @returns 
     */
    async getImg(race:number = -1): Promise<SpriteFrame> {
        let sf:SpriteFrame
        if(race == -1){
            race = UserInfo.instance.race
        }
        try {
            
            if(this.id <=4){
                sf = await ResManager.instance.loadAssetByUrl<SpriteFrame>(`buildings/${this.id}/spriteFrame`)
            } else if (this.id == buildingType.B31_H_Wall || this.id == buildingType.B32_X_Wall ||this.id == buildingType.B33_M_Wall){
                sf = await ResManager.instance.loadAssetByUrl<SpriteFrame>(`cityImg/wall_${race}/spriteFrame`)
            }
            
            else {
                sf = await ResManager.instance.loadAssetByUrl<SpriteFrame>(`buildings/${race}/${this.name}/spriteFrame`)
            }
            
        } catch (error) {
            
            
        }

        if(this.id == 99){
            sf = await ResManager.instance.loadAssetByUrl<SpriteFrame>(`buildings/99/spriteFrame`)
        }

        return sf
    }

    /**
     * 获取正在建造中的建筑
     * @returns 
     */
    async getBuildingImg(): Promise<SpriteFrame> {

        let sf = await ResManager.instance.loadAssetByUrl<SpriteFrame>(`buildings/building/spriteFrame`)

        return sf
    }

    /**
     * 获取建筑物上面的事件
     * @returns 
     */
    getBuildingEvent(): Events {
        let eventList = UserInfo.instance.eventList

        for (let e of eventList) {
            if (e.eType == EventType.advBuild && e.eParam == this.uid + '') {
                return e
            }

            if (e.eType == EventType.destroy && e.eParam == this.uid + '') {
                return e
            }
        }
        return null
    }
    /**
     * 是否正在建造
     */
    get isBuilding(): boolean {
        let event = this.getBuildingEvent()
        if (!event) {
            return false
        }
        if (event.eType == EventType.advBuild) {
            return true
        } else {
            false
        }
    }
    /**
    * 是否正在拆除
    */
    get isRemoving(): boolean {
        let event = this.getBuildingEvent()
        if (!event) {
            return false
        }
        if (event.eType == EventType.destroy) {
            return true
        } else {
            false
        }
    }
    /**
     * 是否满级
     */
    get isMaxLevel(): boolean {
        return this.level >= this.maxLevel
    }

    /**
     * 判断升级的资源够不够
     */
    haveRes(isNextLevel: boolean = true): boolean {
        let nextBuilding: Building
        if (isNextLevel) {
            nextBuilding = Building.createByIdAndLevel(this.id, this.level + 1)
        } else {
            nextBuilding = this
        }

        let villageData = UserInfo.instance.villageData
        let food = villageData.res.food_reserve
        let iron = villageData.res.iron_reserve
        let wood = villageData.res.wood_reserve
        let mud = villageData.res.mud_reserve

        if (food < nextBuilding.food) {
            return false
        }
        if (iron < nextBuilding.iron) {
            return false
        }
        if (wood < nextBuilding.wood) {
            return false
        }
        if (mud < nextBuilding.mud) {
            return false
        }

        return true
    }
    /**
     * 判断钻石够不够
     */
    haveDiamond(): boolean {
        if (this.isBuilding) {
            if (UserInfo.instance.diamond < DiamondConsume.BUILD) {
                return false
            }
        }
        if (this.isRemoving) {
            if (UserInfo.instance.diamond < DiamondConsume.REMOVE) {
                return false
            }
        }


        return true
    }
    /**
     * 判断升级时，粮仓是否足
     */
    isEnoughFood(isNextLevel: boolean = true): boolean {
        let nextBuilding: Building
        if (isNextLevel) {
            nextBuilding = Building.createByIdAndLevel(this.id, this.level + 1)
        } else {
            nextBuilding = this
        }
        let villageData = UserInfo.instance.villageData
        let food_max_reserve = villageData.res.food_max_reserve
        if (nextBuilding.food > food_max_reserve) {
            return false
        }
        return true
    }
    /**
     * 判断升级时，仓库是否足
     */
    isEnoughStore(isNextLevel: boolean = true): boolean {
        let nextBuilding: Building
        if (isNextLevel) {
            nextBuilding = Building.createByIdAndLevel(this.id, this.level + 1)
        } else {
            nextBuilding = this
        }
        let villageData = UserInfo.instance.villageData
        let comm_max_reserve = villageData.res.comm_max_reserve
        let storeCount = nextBuilding.wood + nextBuilding.iron + nextBuilding.mud
        if (nextBuilding.wood > comm_max_reserve) {
            return false
        }
        if (nextBuilding.iron > comm_max_reserve) {
            return false
        }
        if (nextBuilding.mud > comm_max_reserve) {
            return false
        }
        return true
    }
    /**
     * 判断能否在该空地上，建筑这个建筑物
     * @param building 要建筑的建筑物
     * @returns 
     */
    canBuildOnSpace(building: Building): boolean {
        // 只有空地上才能新建
        if (this.id != 0) {
            return false
        }

        let haveUid = false
        for(let key in BuildingCondition){
            let uid = BuildingCondition[key].uid
            if(uid == this.uid ){
                haveUid = true
            }
        }

        if(haveUid){
            if(!BuildingCondition[building.id]){
                return false
            }

            return this.uid == BuildingCondition[building.id].uid
        }


        let condition = BuildingCondition[building.id]
        if (!condition) {
            return true
        }

        if (!condition.uid) {
            return true
        }

        if (condition.uid != this.uid) {
            return false
        }

        return true
    }
    /**
     * 判断是否能够被建造
     */
    get isCanBuild(): boolean {
        let buildings: BManager[] = UserInfo.instance.villageData.bManager.bList
        let condition = BuildingCondition[this.id]
        if (!condition) {
            return true
        }

        // 不允许建造多个的
        if (!condition.multiple) {
            for (let b of buildings) {
                if (this.id == b.gid) {
                    return false
                }
            }
        }

        // 达到满级后，才能再建造的
        if (condition.noneOrMaxLevel) {
            
            let list: BManager[] = []
            for (let b of buildings) {
                if (this.id == b.gid) {
                    list.push(b)
                }
            }
            // 是否有一个是满级
            let isFullLevel = false
            for (let item of list) {
                if (item.grade == this.maxLevel) {
                    isFullLevel =  true
                }
            }
            if(!isFullLevel && list.length > 0){
                return false
            }
        }

        // 不能与某个建筑物共存的
        if (condition.exclude) {
            for (let b of buildings) {
                if (condition.exclude == b.gid) {
                    return false
                }
            }
        }

        // 某个种族特有的
        if (condition.raceType > -1) {

            if (condition.raceType != UserInfo.instance.race) {
                return false
            }
        }

        if (condition.only) {
            // TODO
        }

        // 只能建在附属村，不能建在主村
        if (condition.sub) {
            if (UserInfo.instance.isMainVillage) {
                return false
            }
        }
        // 只能建在住村，不能建在附属村
        if (condition.main) {
            if (!UserInfo.instance.isMainVillage) {
                return false
            }
        }

        // 判断某些建筑物，只能建在特定的位置
        // if (condition.uid) {
        //     if (VillageController.instance.curClickSpace) {
        //         let space = VillageController.instance.curClickSpace.getComponent(Space)
        //         if (space.buildData.uid != condition.uid) {
        //             return false
        //         }
        //     }


        // }

        return true
    }
    /**
     * 获取建造时，依赖其他建筑物的等级
     */
    get needLevel(): any[] {
        let buildings = UserInfo.instance.bList
       
        let needList = []
        let condition = BuildingCondition[this.id]
        if (!condition) {
            return []
        }
        let require = condition.require
        for (let key in require) {
            let id = key
            let level = require[key]
            let buildData = Building.createById(parseInt(id))
            buildData.level = level

            let tempBuild: BManager
            for (let b of buildings) {
                if (b.gid == parseInt(id)) {
                    tempBuild = b
                }
            }
            if (!tempBuild || tempBuild.grade < level) {
               

                needList.push({
                    id: parseInt(id),
                    name: buildData.name,
                    level: level,
                    isLack: true,
                    type: 'building',
                    isExit: tempBuild != null,
                })
            } else {
                needList.push({
                    id: parseInt(id),
                    name: buildData.name,
                    level: level,
                })
            }
        }

        let tech = condition.tech
        for(let key in tech){
            let id = parseInt(key)
            let level = tech[key]

            let myTech = Tech.findById(id)
            if(myTech && myTech.level >= level){
                needList.push({
                    id: id,
                    name: myTech.name,
                    level: level,
                })
            } else {
                myTech = Tech.createById(id)
    
                needList.push({
                    id: id,
                    name: myTech.name,
                    level: level,
                    isLack: true,
                    type:'tech'
                })
            }
        }

        return needList
    }

    
    /**是否有足够的粮食消耗，来支持建造和升级 */
    get isEnoughConsumeForBuild():boolean{
        
        if(this.id == buildingType.B04_Food){
            return true
        }
        let next = Building.createByIdAndLevel(this.id, this.level + 1)
        let addPeople = next.people - this.people
        let villageData = UserInfo.instance.villageData
        return villageData.people + addPeople < villageData.res.food_output
    }

    /**建筑物的增益 */
    get effect():number{
        if (this.id == buildingType.B23_Cranny) {
            if (UserInfo.instance.race == raceType.Gaul) {//高卢拥有两倍的山洞
                return bProperty[this.id][this.level][7] * 2;
            } else {
                return bProperty[this.id][this.level][7];
            }
        } else if (this.id <= 4) {//资源
            return (bProperty[this.id][this.level][7] * UserInfo.instance.config.Output);
        } else {
            return bProperty[this.id][this.level][7];
        }
    }


    get increaseNum():{title:string, levelTitle:string, num:string}{
        if(this.id <= 4){
            return {
                title: '当前生产量', 
                levelTitle: `等级${this.level}的生产量`, 
                num: this.effect + '每小时'
            }
             
        }
        if(this.id == 10){
            return {
                title: '当前存储容量',
                levelTitle: `等级${this.level}的存储容量`,
                num: this.effect + '资源数量'
            }
        }
        if(this.id == 11){
            return {
                title: '当前存储容量',
                levelTitle: `等级${this.level}的存储容量`,
                num: this.effect + '粮食数量'
            }
        }
        if(this.id == 14){
            return {
                title: '当前速度',
                levelTitle: `等级${this.level}的速度`,
                num: this.effect + '%'
            }
        }
        if(this.id == 15){
            return {
                title: '当前建造所需时间',
                levelTitle: `等级${this.level}建造所需时间`,
                num: this.effect + '%'
            }
        }

        if(this.id == 23){
            return {
                title: '当前能够隐藏的最大资源量',
                levelTitle: `等级${this.level}够隐藏的最大资源量`,
                num: this.effect + ''
            }
        }

        if(this.id == 24){
            return {
                title: '可举办活动等级',
                levelTitle: `等级${this.level}可举办活动等级`,
                num: this.effect == 2 ? "大型" : "小型"
            }
        }

        if(this.id == 27){
            return {
                title: '当前宝物存储量',
                levelTitle: `等级${this.level}宝物存储量`,
                num: this.effect + ''
            }
        }
        if(this.id == 31 || this.id == 32 || this.id == 33){
            return {
                title: '当前能够提供的防御力加成',
                levelTitle: `等级${this.level}能够提供的防御力加成`,
                num: this.effect + '%'
            }
        }
        if(this.id == 34){
            return {
                title: '当前能够提供的建筑稳定度加成',
                levelTitle: `等级${this.level}能够提供的建筑稳定度加成`,
                num: this.effect + '%'
            }
        }
        if(this.id == 36){
            return {
                title: '当前防御力',
                levelTitle: `等级${this.level}防御力`,
                num: this.effect*50 + '%'
            }
        }
        if(this.id == 38){
            return {
                title: '当前存储容量',
                levelTitle: `等级${this.level}存储容量`,
                num: this.effect + '资源数量'
            }
        }
        if(this.id == 39){
            return {
                title: '当前存储容量',
                levelTitle: `等级${this.level}存储容量`,
                num: this.effect + '粮食数量'
            }
        }


        return {
            title: '',
            levelTitle: ``,
            num: ''
        }
        
    }

    /**
     * 等比缩放图片，让图片适应在父节点内
     * @param cover 
     * @param sprite 
     */
    static setCoverSize(cover:Node, sprite:Sprite){
        if(!sprite.spriteFrame){
            return
        }
        let size = cover.getComponent(UITransform).contentSize
        
        let rect = sprite.spriteFrame.rect
       
        let r = 1
        if(rect.width > rect.height){
            r = rect.width / size.width
        } else {
            r = rect.height / size.height
        }
        let s = new Size(rect.width / r, rect.height / r)
        sprite.node.getComponent(UITransform).setContentSize(s)
    }

}










